home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Vogle driver for Sun using sunview.
- *
- */
- #include <stdio.h>
-
- #include <suntool/sunview.h>
- #include <fcntl.h>
- #include <errno.h>
-
- #ifdef SUN_3_5
- #define event_action event_id
- #endif
-
- #include "vogl.h"
-
- #define STDMAPSIZE 16 /* map that can be used with buffering */
- #define CMAPSIZE 256
- #define STDFONTDIR "/usr/lib/fonts/fixedwidthfonts/"
-
- #define MIN(x,y) ((x) < (y) ? (x) : (y))
- #define COL(c) ((usememory) ? (c) : (c) | ((c << 4)))
-
- #define OP_WHITE (PIX_SRC | PIX_COLOR(COL(7)) | PIX_DONTCLIP)
- #define OP_BLACK (PIX_SRC | PIX_COLOR(COL(0)) | PIX_DONTCLIP)
- #define COL_WHITE COL(7)
- #define COL_BLACK COL(0)
-
- static Pixwin *pw_tmp, *pw;
-
- #ifdef BASE_COL_SET
- static Pixwin *pw0;
- #endif
-
- static Pixrect *frontb, *backb;
- static Pixfont *font_id;
- static int inbackb;
- static int wfd, blanket_win;
- static int oldflags;
- static int pwfd, h, w;
- static int colour, usememory, fmask, bmask, shift;
- static u_char fr[CMAPSIZE], fg[CMAPSIZE], fb[CMAPSIZE];
- static u_char br[CMAPSIZE], bg[CMAPSIZE], bb[CMAPSIZE];
- static u_char *red, *green, *blue;
-
- /*
- * default colour map
- */
- static u_char defred[STDMAPSIZE] = {
- 0, 255, 0, 255, 0, 255, 0, 255, 0,
- },
- defgreen[STDMAPSIZE] = {
- 0, 0, 255, 255, 0, 0, 255, 255, 0,
- },
- defblue[STDMAPSIZE] = {
- 0, 0, 0, 0, 255, 255, 255, 255, 0,
- };
-
- /*
- * redisplay
- *
- * redisplay the window.
- */
- static void
- redisplay()
- {
- pw_damaged(pw);
-
- pw_repairretained(pw);
-
- pw_donedamaged(pw);
- }
-
- /*
- * SUN_init
- *
- * initialises drawing canvas to occupy current window
- */
- SUN_init()
- {
- int i, prefx, prefy, prefxs, prefys, bw;
- char name[WIN_NAMESIZE];
- Inputmask imk, imp;
- Rect rect;
- int rootfd;
-
- pw = (Pixwin *)NULL;
-
- #ifdef BASE_COL_SET
- pw0 = pw;
- #endif
-
- /*
- * get the gfx win so we have some default sizes to use
- */
- we_getgfxwindow(name);
- pwfd = open(name, 2);
- win_getrect(pwfd, &rect);
-
- /*
- * Get the input masks of the base window...
- */
- win_get_pick_mask(pwfd, &imp);
- win_get_kbd_mask(pwfd, &imk);
-
-
- /*
- * get a new window (either going to be a blanket window or
- * a window in it's own right)
- */
- if ((wfd = win_getnewwindow()) == -1) {
- fprintf(stderr, "No new windows!\n");
- exit(1);
- }
-
- getprefposandsize(&prefx, &prefy, &prefxs, &prefys);
-
- if (prefx > -1) {
- rect.r_left = prefx;
- rect.r_top = prefy;
- }
-
- if (prefxs > -1) {
- rect.r_width = prefxs;
- rect.r_height = prefys;
- }
-
- w = rect.r_width;
- h = rect.r_height;
-
- bw = 3;
- if (prefx > -1 || prefxs > -1) {
- /*
- * Make room for a 3 pixel border
- */
- if (rect.r_left <= 2)
- rect.r_left = 0;
- else
- rect.r_left -= bw;
-
- if (rect.r_top <= 2)
- rect.r_top = 0;
- else
- rect.r_top -= bw;
-
- rect.r_width += 2 * bw;
- rect.r_height += 2 * bw;
-
- win_setrect(wfd, &rect);
-
- /*
- * get the parent (probably full screen window)
- * so we can size our window to any size we like
- * on the screen.
- */
- we_getparentwindow(name);
- rootfd = open(name, 2);
-
- win_setlink(wfd, WL_PARENT, win_fdtonumber(rootfd));
- win_setlink(wfd, WL_COVERED, WIN_NULLLINK);
- win_insert(wfd);
-
- wmgr_top(wfd, rootfd);
-
- pw = pw_open(wfd);
-
- #ifdef BASE_COL_SET
- /*
- * Get the pixrect for the window that we started in
- * so we can set it's colourmap as well
- */
- pw0 = pw_open(pwfd);
- #endif
-
- close(rootfd);
- blanket_win = 0;
- } else {
- win_insertblanket(wfd, pwfd);
- pw = pw_region(pw_open(wfd), 0, 0, w, h);
- blanket_win = 1;
- }
-
- /*
- * Set non-blocking input for window.
- */
- oldflags = fcntl(wfd, F_GETFL, 0);
- if (fcntl(wfd, F_SETFL, FNDELAY) < 0) {
- perror("F_SETFL");
- exit(1);
- }
-
- /*
- * Setup the input masks for window.
- */
-
- win_set_kbd_mask(wfd, &imk);
- win_set_pick_mask(wfd, &imp);
-
- vdevice.depth = pw->pw_pixrect->pr_depth;
-
- /*
- * Set up the color map.
- */
-
- for (i = 0; i < CMAPSIZE; i++) {
- fr[i] = defred[i & 0x0f];
- fg[i] = defgreen[i & 0x0f];
- fb[i] = defblue[i & 0x0f];
-
- br[i] = defred[(i & 0xf0) >> 4];
- bg[i] = defgreen[(i & 0xf0) >> 4];
- bb[i] = defblue[(i & 0xf0) >> 4];
- }
-
- fr[255] = fg[255] = fb[255] = 255;
- br[255] = bg[255] = bb[255] = 255;
-
- red = fr;
- green = fg;
- blue = fb;
-
- if (vdevice.depth > 1) {
- pw_setcmsname(pw, "vogl");
- pw_putcolormap(pw, 0, CMAPSIZE, fr, fg, fb);
- #ifdef BASE_COL_SET
- if (pw0 != (Pixwin *)NULL) {
- pw_setcmsname(pw0, "vogl");
- pw_putcolormap(pw0, 0, CMAPSIZE, fr, fg, fb);
- }
- #endif
- }
-
- if (prefx > -1 || prefxs > -1) {
- /*
- * Draw the border...
- */
- int x0, y0, x1, y1;
-
- x0 = y0 = 0;
- x1 = rect.r_width - 1;
- y1 = 0;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 2, y0 + 2, x1 - 2, y1 + 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 1, y0 + 1, x1 - 1, y1 + 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = x0;
- y1 = rect.r_height - 1;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 2, y0 + 2, x1 - 2, y1 - 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 1, y0 + 1, x1 - 1, y1 - 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = 0;
- y1 = rect.r_height - 1;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 2, y0 - 2, x1 + 2, y1 - 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 - 1, y0 - 1, x1 + 1, y1 - 1, OP_BLACK, COL_BLACK);
- x0 = x1;
- y0 = y1;
- x1 = 0;
- y1 = 0;
- pw_vector(pw, x0, y0, x1, y1, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 2, y0 - 2, x1 + 2, y1 + 2, OP_WHITE, COL_WHITE);
- pw_vector(pw, x0 + 1, y0 - 1, x1 + 1, y1 + 1, OP_BLACK, COL_BLACK);
-
- pw_tmp = pw;
- pw = pw_region(pw_tmp, 3, 3, w, h);
- pw_close(pw_tmp);
- }
-
-
- frontb = pw->pw_prretained = mem_create(w, h, vdevice.depth);
- backb = (Pixrect *)NULL;
-
- fmask = 0xf0;
- bmask = 0x0f;
-
- signal(SIGWINCH, redisplay);
-
- /*
- * Let VOGLE know about the window size.
- */
- vdevice.sizeX = vdevice.sizeY = MIN(w, h);
- vdevice.sizeSx = w;
- vdevice.sizeSy = h;
-
- return(1);
- }
-
- /*
- * SUN_exit
- *
- * cleans up before returning the window to normal.
- */
- SUN_exit()
- {
- long nbytes;
- int i;
- Event event;
-
- /*
- * Flush all events for this window.
- *
- * While doing non-blocking input input_readevent returns -1 and
- * errno == EWOULDBLOCK when everything has been read, so if
- * errno != EWOULDBLOCK then something naughty happened...
- */
- while (input_readevent(wfd, &event) >= 0)
- ;
-
- if (errno != EWOULDBLOCK) {
- perror("SUN_exit(flushing), input_readevent");
- exit();
- }
-
- /*
- * reset wfd to blocking input.
- */
- if (fcntl(wfd, F_SETFL, oldflags) < 0) {
- perror("oldflags, F_SETFL");
- exit(1);
- }
-
- if (blanket_win)
- win_removeblanket(wfd);
- else
- win_remove(wfd);
-
- signal(SIGWINCH, SIG_DFL);
-
- return(1);
- }
-
- /*
- * SUN_draw
- *
- * draws a line from the current graphics position to (x, y).
- *
- * Note: (0, 0) is defined as the top left of the window on a sun (easy
- * to forget).
- */
- SUN_draw(x, y)
- int x, y;
- {
- pw_vector(pw, vdevice.cpVx, vdevice.sizeSy - vdevice.cpVy, x, vdevice.sizeSy - y, PIX_SRC | PIX_COLOR(COL(colour)), COL(colour));
- }
-
- /*
- * SUN_getkey
- *
- * grab a character from the keyboard.
- */
- int
- SUN_getkey()
- {
- Event event;
-
- do {
- while ((input_readevent(wfd, &event) < 0) && (errno == EWOULDBLOCK))
- ; /* Nothing to read - wait for something */
-
- } while (!event_is_ascii(&event)); /* Wait for a key press */
-
- return(event_action(&event));
- }
-
- /*
- * SUN_checkkey
- *
- * Check if a keyboard key has been hit. If so return it.
- */
-
- int
- SUN_checkkey()
- {
- Event event;
-
- if (input_readevent(wfd, &event) < 0) {
- if (errno == EWOULDBLOCK) {
- return(0);
- } else {
- perror("SUN_checkkey, input_readevent");
- exit(1);
- }
- } else if (event_is_ascii(&event))
- return(event_action(&event));
-
- return(0);
- }
-
-
- /*
- * SUN_locator
- *
- * return the window location of the cursor, plus which mouse button,
- * if any, is been pressed.
- */
- int
- SUN_locator(wx, wy)
- int *wx, *wy;
- {
- int but;
- Event event;
-
- but = 0;
-
- *wx = win_get_vuid_value(wfd, LOC_X_ABSOLUTE);
- *wy = (int)vdevice.sizeSy - win_get_vuid_value(wfd, LOC_Y_ABSOLUTE);
-
- /* This used to work under 4.0 but not longer ..... Maybe
- * SUN don't want us to use sunview anymore?
- if (win_get_vuid_value(wfd, BUT(1)))
- but |= 1;
-
- if (win_get_vuid_value(wfd, BUT(2)))
- but |= 2;
-
- if (win_get_vuid_value(wfd, BUT(3)))
- but |= 3;
- */
-
-
- if (input_readevent(wfd, &event) < 0) {
- if (errno == EWOULDBLOCK) {
- return(0);
- } else {
- perror("SUN_locator, input_readevent");
- exit(1);
- }
- } else {
- if (event_is_down(&event)) {
- if (event_action(&event) == MS_LEFT)
- but |= 1;
- if (event_action(&event) == MS_MIDDLE)
- but |= 2;
- if (event_action(&event) == MS_RIGHT)
- but |= 4;
- }
- }
-
- return(but);
- }
-
- /*
- * SUN_clear
- *
- * Clear the screen to current colour
- */
- SUN_clear()
- {
- int x[4], y[4];
-
- if (vdevice.maxVx != vdevice.sizeSx
- || vdevice.maxVy != vdevice.sizeSy
- || vdevice.minVx != 0
- || vdevice.minVy != 0) {
- x[0] = x[3] = vdevice.minVx;
- y[0] = y[1] = vdevice.maxVy;
- y[2] = y[3] = vdevice.minVy;
- x[1] = x[2] = vdevice.maxVx;
-
- SUN_fill(4, x, y);
- } else {
- pw_writebackground(pw, 0, 0, w, h, PIX_SRC | PIX_COLOR(COL(colour)) | PIX_DONTCLIP);
- }
- }
-
- /*
- * SUN_color
- *
- * set the current drawing color index.
- */
- SUN_color(ind)
- int ind;
- {
- colour = ind;
- }
-
- /*
- * SUN_mapcolor
- *
- * change index i in the color map to the appropriate r, g, b, value.
- */
- SUN_mapcolor(i, r, g, b)
- int i;
- int r, g, b;
- {
- int j;
-
- if (i >= 255 || vdevice.depth == 1)
- return(-1);
-
- fr[i] = (u_char)r;
- fg[i] = (u_char)g;
- fb[i] = (u_char)b;
-
- if (i > 15)
- usememory = 1;
- else {
- defred[i] = r;
- defgreen[i] = g;
- defblue[i] = b;
-
- for (j = 0; j < CMAPSIZE; j++) {
- fr[i] = defred[j & 0x0f];
- fg[i] = defgreen[j & 0x0f];
- fb[i] = defblue[j & 0x0f];
-
- br[i] = defred[(j & 0xf0) >> 4];
- bg[i] = defgreen[(j & 0xf0) >> 4];
- bb[i] = defblue[(j & 0xf0) >> 4];
- }
- }
-
- /*
- * gaurantee that background and forground differ
- */
- fr[255] = (u_char)~fr[0];
- fg[255] = (u_char)~fg[0];
- fb[255] = (u_char)~fb[0];
-
- br[255] = (u_char)~br[0];
- bg[255] = (u_char)~bg[0];
- bb[255] = (u_char)~bb[0];
-
- pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
- }
-
- /*
- * SUN_font
- *
- * Set up a hardware font. Return 1 on success 0 otherwise.
- *
- */
- SUN_font(fontfile)
- char *fontfile;
- {
- char name[BUFSIZ];
-
- if (font_id != (Pixfont *)NULL)
- pf_close(font_id);
-
- if ((font_id = pf_open(fontfile)) == NULL)
- if (*fontfile != '/') {
- strcpy(name, STDFONTDIR);
- strcat(name, fontfile);
- if ((font_id = pf_open(name)) == NULL)
- return(0);
- } else
- return(0);
-
- vdevice.hheight = font_id->pf_defaultsize.y;
- vdevice.hwidth = font_id->pf_defaultsize.x;
-
- return(1);
- }
-
- /*
- * SUN_char
- *
- * outputs one char - is more complicated for other devices
- */
- SUN_char(c)
- char c;
- {
- char *s = " ";
-
- s[0] = c;
- pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(COL(colour)), font_id, s);
- }
-
- /*
- * SUN_string
- *
- * Display a string at the current drawing position.
- */
- SUN_string(s)
- char s[];
- {
- pw_ttext(pw, vdevice.cpVx, (int)(vdevice.sizeSy - vdevice.cpVy), PIX_SRC | PIX_COLOR(COL(colour)), font_id, s);
- }
-
- /*
- * SUN_fill
- *
- * fill a polygon
- */
- SUN_fill(n, x, y)
- int n, x[], y[];
- {
- struct pr_pos vlist[128];
- int i, npnts;
-
- if (n > 128)
- verror("vogl: more than 128 points in a polygon");
-
- npnts = n;
-
- for (i = 0; i < n; i++) {
- vlist[i].x = x[i];
- vlist[i].y = vdevice.sizeSy - y[i];
- }
-
- pw_polygon_2(pw, 0, 0, 1, &npnts, vlist, PIX_SRC | PIX_COLOR(COL(colour)) | PIX_DONTCLIP, (Pixwin *)NULL, 0, 0);
-
- vdevice.cpVx = x[n-1];
- vdevice.cpVy = y[n-1];
- }
-
- /*
- * SUN_backb
- *
- * swap to memory only drawing (backbuffer) - a little slow but it
- * works on everything. Where we can, we use the frame buffer.
- */
- SUN_backb()
- {
- int mask = 0xff;
-
- if (vdevice.depth == 1 || usememory) {
- if (vdevice.depth > 1)
- pw_putattributes(pw, &mask);
-
- if (backb == (Pixrect *)NULL) {
- if ((backb = mem_create((int)vdevice.sizeSx, (int)vdevice.sizeSy, vdevice.depth)) == (Pixrect *)NULL)
- return(-1);
- }
-
- if (pw->pw_prretained == backb)
- pw->pw_prretained = frontb;
- else
- pw->pw_prretained = backb;
-
- pw_batch_on(pw);
- } else {
- pw_getattributes(pw, &mask);
- if (mask == bmask) {
- red = fr;
- green = fg;
- blue = fb;
- pw_putattributes(pw, &fmask);
- } else {
- red = br;
- green = bg;
- blue = bb;
- pw_putattributes(pw, &bmask);
- }
-
- pw_setcmsname(pw, "vogl");
- pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
- }
-
- return(0);
- }
-
- /*
- * SUN_swapb
- *
- * swap the front and back buffers.
- */
- SUN_swapb()
- {
- int mask = 0xff;
-
- if (vdevice.depth == 1 || usememory) {
- if (vdevice.depth > 1)
- pw_putattributes(pw, &mask);
-
- if (vdevice.inbackbuffer) {
- pw_batch_off(pw);
- if (pw->pw_prretained == backb)
- pw->pw_prretained = frontb;
- else
- pw->pw_prretained = backb;
- pw_batch_on(pw);
- } else {
- if (backb == (Pixrect *)NULL) {
- if ((backb = mem_create((int)vdevice.sizeSx, (int)vdevice.sizeSy, vdevice.depth)) == (Pixrect *)NULL)
- return(-1);
- }
-
- if (pw->pw_prretained == backb)
- pw->pw_prretained = frontb;
- else
- pw->pw_prretained = backb;
- }
- } else {
-
- pw_getattributes(pw, &mask);
- if (mask == bmask) {
- red = fr;
- green = fg;
- blue = fb;
- if (vdevice.inbackbuffer)
- pw_putattributes(pw, &fmask);
- } else {
- red = br;
- green = bg;
- blue = bb;
- if (vdevice.inbackbuffer)
- pw_putattributes(pw, &bmask);
- }
-
- pw_putcolormap(pw, 0, CMAPSIZE, red, green, blue);
- }
-
- return(0);
- }
-
- /*
- * SUN_frontb
- *
- * draw in the front buffer
- */
- SUN_frontb()
- {
- int mask;
-
- if (vdevice.depth == 1 || usememory)
- pw_batch_off(pw);
- else {
- if (vdevice.inbackbuffer) {
- mask = 0xff;
- pw_putattributes(pw, &mask);
- }
- }
- }
-
- /*
- * the device entry
- */
- static DevEntry sundev = {
- "sun",
- "screen.b.16",
- "screen.b.12",
- SUN_backb,
- SUN_char,
- SUN_checkkey,
- SUN_clear,
- SUN_color,
- SUN_draw,
- SUN_exit,
- SUN_fill,
- SUN_font,
- SUN_frontb,
- SUN_getkey,
- SUN_init,
- SUN_locator,
- SUN_mapcolor,
- SUN_string,
- SUN_swapb
- };
-
- /*
- * _SUN_devcpy
- *
- * copy the sun device into vdevice.dev.
- */
- _SUN_devcpy()
- {
- vdevice.dev = sundev;
- }
-